<script setup>
/**
 * 商品新增页面，所有部分在点击保存后统一保存
 */

import { ref, onMounted } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import { convertToFormData } from '@/utilities/common';
import router from '@/router';
import CommodityCategorySelect from './components/CommodityCategorySelect.vue';
import CommoditySKUEdit from './components/CommoditySKUEdit.vue';

import {
  addCommodity,
  uploadCommodityMainImage,
  uploadCommoditySlideShowImage,
  uploadCommoditySKUImage
} from '@/apis/commodity';

onMounted(() => {
  mainModel.value = {};
  slideShowImageList.value = [];
  skuTableData.value = [];
});

/* 商品主信息 */
const mainModelRef = ref();
const mainModel = ref({});

let mainImageRaw;
const onMainImageSelectFile = (uploadFile) => {
  mainModel.value.mainImageUrl = URL.createObjectURL(uploadFile.raw);
  mainImageRaw = uploadFile.raw;
};

const rules = ref({
  commodityName: [
    { required: true, message: '请输入商品名称', trigger: 'blur' }
  ],
  intro: [{ required: true, message: '请输入商品简介', trigger: 'blur' }],
  manufacture: [{ required: true, message: '请输入制造商', trigger: 'blur' }]
});

/* 商品轮播图片 */
const slideShowImageList = ref([]);
const onSlideShowImageSelectFile = (uploadFile) => {
  slideShowImageList.value.push({
    name: uploadFile.name,
    url: uploadFile.url,
    raw: uploadFile.raw
  });
};

const handleExceed = () => {
  ElMessage.error('最多只能上传 4 张图片');
};

const isShowPrevieImage = ref(false);
const previewImageUrl = ref();
const handleImagePreview = (uploadFile) => {
  previewImageUrl.value = uploadFile.url;
  isShowPrevieImage.value = true;
};

/* SKU 信息 */
const skuTableData = ref([]);
const skuEditRef = ref();

const onCellClick = (row, column) => {
  if (column.no !== 0) {
    return;
  } else {
    // 当点击图片单元格时，预览图片
    previewImageUrl.value = row.skuImageUrl;
    isShowPrevieImage.value = true;
  }
};

const addSKU = () => {
  skuEditRef.value.open('add', -1, {});
};

const editSKU = (scope) => {
  skuEditRef.value.open('add', scope.$index, scope.row);
};

const deleteSKU = (scope) => {
  skuTableData.value.splice(scope.$index, 1);
};

const onFinishEditSKU = (optMode, targetIndex, skuModel) => {
  if (targetIndex === -1) {
    skuTableData.value.push(skuModel);
  } else {
    skuTableData.value[targetIndex] = skuModel;
  }
  ElMessage.info('已添加 SKU，将随商品一起保存！');
};

const saveAll = async () => {
  /* 商品主信息 */
  await mainModelRef.value.validate();
  if (!mainModel.value.mainImageUrl) {
    ElMessage.error('请上传商品主图');
    return;
  }

  let imgUploadArr = [];

  // 添加主图上传的 Promise
  imgUploadArr.push(
    uploadCommodityMainImage(
      convertToFormData({
        name: mainImageRaw.name,
        file: mainImageRaw
      })
    )
  );

  // 添加轮播图上传的 Promise
  let slideShowImgUploadArr = slideShowImageList.value.map((item) => {
    return uploadCommoditySlideShowImage(
      convertToFormData({
        name: item.name,
        file: item.raw
      })
    );
  });
  imgUploadArr = imgUploadArr.concat(slideShowImgUploadArr);

  // 添加 SKU 图片上传的 Promise
  let skuImgUplodArr = skuTableData.value.map((item) => {
    return uploadCommoditySKUImage(
      convertToFormData({
        name: item.skuImageRaw.name,
        file: item.skuImageRaw
      })
    );
  });
  imgUploadArr = imgUploadArr.concat(skuImgUplodArr);

  Promise.all(imgUploadArr)
    .then(async (resultArr) => {
      ElMessage.success('图片全部上传成功');

      /* 分配上传图片的结果 */
      let mainResult = resultArr[0];
      let slideShowImgResultArr = resultArr.slice(
        1,
        slideShowImgUploadArr.length + 1
      );
      let skuImgResultArr = resultArr.slice(1 + slideShowImgUploadArr.length);

      /* 准备商品主信息数据 */
      let mainReqData = JSON.parse(JSON.stringify(mainModel.value));
      mainReqData.mainImageUrl = mainResult.data;

      /* 准备商品轮播图数据 */
      let slideShowImageReqData = [];
      slideShowImgResultArr.forEach((value, index) => {
        slideShowImageReqData.push({
          imageUrl: value.data,
          sortNum: index
        });
      });

      /* 准备商品 SKU 数据*/
      let skuReqData = [];
      skuTableData.value.forEach((value, index) => {
        let itemTemp = { ...value };
        delete itemTemp.skuImageRaw;
        itemTemp.skuImageUrl = skuImgResultArr[index].data;
        skuReqData.push(itemTemp);
      });

      /* 统一调用接口 */
      let res = await addCommodity({
        mainItem: mainReqData,
        imageDtoItems: slideShowImageReqData,
        skudtoItems: skuReqData
      });
      ElMessage.success(res.msg);
      router.back();
    })
    .catch((err) => {
      ElMessage.error(err.message);
    });
};
</script>
<template>
  <div class="container">
    <div class="title-container">
      <h2 class="title">新增商品</h2>
      <div class="ops">
        <el-button @click="saveAll()">保存修改</el-button>
      </div>
    </div>
    <div class="main-info-container">
      <div class="title-container">
        <h2 class="title">商品信息</h2>
        <div class="ops"></div>
      </div>
      <el-form
        ref="mainModelRef"
        :model="mainModel"
        :rules="rules"
        label-width="100px"
        label-position="top"
      >
        <div class="main-image-container">
          <el-upload
            class="main-image-uploader"
            :auto-upload="false"
            :show-file-list="false"
            :on-change="onMainImageSelectFile"
          >
            <img
              v-if="mainModel.mainImageUrl"
              :src="mainModel.mainImageUrl"
              class="main-image"
            />
            <el-icon v-else class="main-image-uploader-icon"><Plus /></el-icon>
          </el-upload>
        </div>
        <div class="info-container">
          <el-form-item
            class="input-item"
            label="商品名称"
            prop="commodityName"
          >
            <el-input v-model="mainModel.commodityName" />
          </el-form-item>
          <el-form-item class="input-item input-item-after" label="商品分类">
            <commodity-category-select
              v-model="mainModel.categoryId"
            ></commodity-category-select>
          </el-form-item>
          <el-form-item class="input-item" label="制造商" prop="manufacture">
            <el-input v-model="mainModel.manufacture" />
          </el-form-item>
          <el-form-item label="简介" prop="intro">
            <el-input
              type="textarea"
              v-model="mainModel.intro"
              resize="none"
              :rows="3"
              :maxlength="50"
              :show-word-limit="true"
            />
          </el-form-item>
        </div>
      </el-form>
    </div>
    <div class="images-container">
      <div class="title-container">
        <h2 class="title">商品轮播图</h2>
        <div class="ops"></div>
      </div>
      <div>
        <el-upload
          v-model:file-list="slideShowImageList"
          list-type="picture-card"
          :auto-upload="false"
          :on-change="onSlideShowImageSelectFile"
          :on-preview="handleImagePreview"
          :on-exceed="handleExceed"
          :limit="4"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
      </div>
    </div>
    <div class="skus-container">
      <div class="title-container">
        <h2 class="title">SKU</h2>
        <div class="ops">
          <el-button @click="addSKU">新增 SKU</el-button>
        </div>
      </div>
      <el-table
        :data="skuTableData"
        style="width: 100%"
        @cell-click="onCellClick"
      >
        <el-table-column label="图片" width="180">
          <template #default="scope">
            <img
              style="width: 50px; height: 50px"
              :src="scope.row.skuImageUrl"
            />
          </template>
        </el-table-column>
        <el-table-column prop="skuName" label="名称" width="180" />
        <el-table-column prop="quantity" label="数量" width="180" />
        <el-table-column prop="price" label="价格" width="180" />
        <el-table-column label="操作">
          <template #default="scope">
            <el-button type="info" @click="editSKU(scope)">编辑</el-button>
            <el-button type="danger" @click="deleteSKU(scope)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <CommoditySKUEdit
      @finishEditSKU="onFinishEditSKU"
      ref="skuEditRef"
    ></CommoditySKUEdit>
    <!-- <div class="detail-container"></div> -->

    <el-dialog v-model="isShowPrevieImage" width="30%">
      <img style="width: 100%; height: 100%" :src="previewImageUrl" />
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.container {
  width: 1000px;
  height: 900px;
  //background-color: pink;
}

.title-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.main-info-container {
  .main-image-container {
    display: inline-block;
    vertical-align: top;
    width: 300px;
    height: 300px;

    .main-image-uploader {
      padding: 10px;

      .main-image {
        width: 280px;
        height: 280px;
        display: block;
      }

      :deep(.el-upload) {
        border: 1px dashed var(--el-border-color);
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        transition: var(--el-transition-duration-fast);
      }

      :deep(.el-upload:hover) {
        border-color: var(--el-color-primary);
      }

      :deep(.el-icon.main-image-uploader-icon) {
        font-size: 28px;
        color: #8c939d;
        width: 280px;
        height: 280px;
        text-align: center;
      }
    }
  }
  .info-container {
    box-sizing: border-box;
    display: inline-block;
    vertical-align: top;
    padding: 10px;
    width: 700px;
    height: 300px;

    .input-item {
      display: inline-block;

      :deep(.el-input) {
        width: 330px;
      }
    }

    .input-item-after {
      margin-left: 20px;
    }
  }
}
</style>

<style></style>
